package com.situ.mall.product.controller;


import com.baomidou.mybatisplus.core.metadata.IPage;
import com.situ.mall.common.util.Result;
import com.situ.mall.pojo.entity.product.Product;
import com.situ.mall.product.pojo.query.ProductQuery;
import com.situ.mall.product.pojo.vo.ProductVO;
import com.situ.mall.product.service.IProductService;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 商品 前端控制器
 * </p>
 *
 * @author Gao
 * @since 2024-10-09
 */
@RestController
@RequestMapping("/product")
public class ProductController {
    @Autowired
    private IProductService productService;

    @GetMapping("/list")
    public Result<IPage<ProductVO>> list(ProductQuery productQuery) {
        IPage<ProductVO> page = productService.list(productQuery);
        //List<Product> records = page.getRecords();
        //long total = page.getTotal();
        return Result.ok(page);
    }

    @PostMapping("/add")
    public Result add(@RequestBody Product product) {
        productService.save(product);
        return Result.ok("添加成功");
    }

    @GetMapping("/selectById/{id}")
    public Result selectById(@PathVariable Long id) {
        Product product = productService.selectById(id);
        return Result.ok(product);
    }

    @PutMapping("/update")
    public Result update(@RequestBody Product product) {
        productService.update(product);
        return Result.ok("更新成功");
    }

    @GetMapping("/selectPromoProduct")
    public Result<List<Product>> selectPromoProduct(String categoryName) {
        List<Product> list =  productService.selectPromoProduct(categoryName);
        return Result.ok(list);
    }

    @Autowired
    private RedissonClient redissonClient;


    @GetMapping("/hello")
    public String hello() {
        //1、获取一把锁，只要锁的名字一样，就是同一把锁
        RLock lock = redissonClient.getLock("my-lock");
        //2、加锁  阻塞式等待。默认加的锁都是30s,lockWatchdogTimeout = 30 * 1000 【看门狗默认时间】
        lock.lock();
        //1）、锁的自动续期，如果业务超长，运行期间自动锁上新的30s。不用担心业务时间长，锁自动过期被删掉
        //只要占锁成功，就会启动一个定时任务【重新给锁设置过期时间，新的过期时间就是看门狗的默认时间】,每隔10秒都会自动的再次续期，续成30秒
        // internalLockLeaseTime 【看门狗时间】 / 3， 10s
        //2）、加锁的业务只要运行完成，就不会给当前锁续期，即使不手动解锁，锁默认会在30s内自动过期，不会产生死锁问题
        try {
            System.out.println("加锁成功，执行业务..." + Thread.currentThread().getId());
            try { TimeUnit.SECONDS.sleep(70); } catch (InterruptedException e) { e.printStackTrace(); }
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            //3、解锁  假设解锁代码没有运行，Redisson会不会出现死锁
            System.out.println("释放锁..." + Thread.currentThread().getId());
            lock.unlock();
        }

        return "hello";
    }


}

